`timescale 1ps/1ps
/* verilator lint_off CASEINCOMPLETE */
// AHB接口的AES
/*  CSR          0x0000          4
    data：    (0x0004 - 0x0010)  128   
    out ：    (0x0014 - 0x0020)  128
*/
module top (
    // AHB Slave Port
    output	wire	[31:0]	AHB_HRDATA,
	output	wire			AHB_HREADY,
	output	wire	[ 0:0]	AHB_HRESP,

	input	wire	[ 1:0]  AHB_HTRANS,
	input	wire	[ 2:0]  AHB_HBURST,

	input	wire	[ 3:0]  AHB_HPROT,
    
	input	wire	[ 2:0]	AHB_HSIZE,
	input	wire			AHB_HWRITE,
	input	wire			AHB_HMASTLOCK,
	input	wire	[ 3:0]	AHB_HMASTER,
	input	wire	[31:0]	AHB_HADDR,
	input	wire	[31:0]  AHB_HWDATA,
	input	wire			AHB_HSEL,
	input	wire			AHB_HCLK,
	input	wire			AHB_HRESETn
);
//The AHB BUS is always ready
assign AHB_HREADY = 1'b1; //ready signal, slave to MCU master
//Response OKAY
assign AHB_HRESP  = 'd0;//response signal, slave to MCU master

//Define Reg for AHB BUS
reg [31:0]  ahb_address;
reg 		ahb_control;
reg         ahb_sel;
reg         ahb_htrans;

always @(posedge AHB_HCLK or negedge AHB_HRESETn) 
    if(~AHB_HRESETn)begin
        ahb_address  <= 32'd0;
        ahb_control  <= 1'b0;
        ahb_sel      <= 1'b0;
        ahb_htrans   <= 1'b0;
    end else begin			  
        ahb_address  <= AHB_HADDR;
        ahb_control  <= AHB_HWRITE;
        ahb_sel      <= AHB_HSEL;
        ahb_htrans   <= AHB_HTRANS[1];
    end

wire write_enable = ahb_htrans & ahb_control    & ahb_sel;
wire read_enable  = ahb_htrans & (!ahb_control) & ahb_sel;

// reg  [127:0]  key_reg;
reg  [127:0]  data_reg;
reg  [127:0]  out_reg;
wire [127:0]  outtxt;
wire  keyexp_done;
wire  encode_done;

//write data to AHB bus
always @(posedge AHB_HCLK or negedge AHB_HRESETn)
    if(~AHB_HRESETn) begin
        // key_reg  <= 'd0;
        data_reg <= 'd0;
    end else if(write_enable) begin
        case (ahb_address[15:0])
            /* 数据 */
            16'h0004: data_reg[127:96] <= AHB_HWDATA;
            16'h0008: data_reg[ 95:64] <= AHB_HWDATA;
            16'h000C: data_reg[ 63:32] <= AHB_HWDATA;
            16'h0010: data_reg[ 31: 0] <= AHB_HWDATA;
            // /* 结果 */
            // 16'h0014: out_reg[127:96] <= AHB_HWDATA;
            // 16'h0018: out_reg[ 95:64] <= AHB_HWDATA;
            // 16'h001C: out_reg[ 63:32] <= AHB_HWDATA;
            // 16'h0020: out_reg[ 31: 0] <= AHB_HWDATA;
        endcase
    end

reg   keyexp,encode,key_state,encode_state;
/* 启动脉冲 */
always @(posedge AHB_HCLK or negedge AHB_HRESETn)
    if(~AHB_HRESETn)
        {keyexp,encode} <= 2'b00; 
    else if(write_enable && (ahb_address[15:0] == 16'h0000))
        {keyexp,encode} <= AHB_HWDATA[3:2];
    else 
        {keyexp,encode} <= 2'b00; 

/* 密钥扩展完成状态位 */
always @(posedge AHB_HCLK or negedge AHB_HRESETn)
    if(~AHB_HRESETn)
        key_state <= 1'b0; 
    else if(keyexp_done)
        key_state <= 1'b1;
    else if(read_enable && (ahb_address[15:0] == 16'h0000))
        key_state <= 1'b0;

/* 加密完成状态位 */
always @(posedge AHB_HCLK or negedge AHB_HRESETn)
    if(~AHB_HRESETn)
        encode_state <= 1'b0; 
    else if(encode_done)
        encode_state <= 1'b1;
    else if(read_enable && (ahb_address[15:0] == 16'h0000))
        encode_state <= 1'b0;

//计算结果
always @(posedge AHB_HCLK or negedge AHB_HRESETn)
    if(~AHB_HRESETn)
        out_reg <= 'd0; 
    else if(encode_done)
        out_reg <= outtxt;

//register address
reg [31:0] ahb_rdata;
always @(*)
    if(read_enable)  begin
        case (ahb_address[15:0])
            16'h0000: ahb_rdata = {28'd0,keyexp,encode,key_state,encode_state};
            /* 数据 */
            16'h0004: ahb_rdata = data_reg[127:96];
            16'h0008: ahb_rdata = data_reg[ 95:64];
            16'h000C: ahb_rdata = data_reg[ 63:32];
            16'h0010: ahb_rdata = data_reg[ 31: 0];
            /* 结果 */
            16'h0014: ahb_rdata = out_reg[127:96];
            16'h0018: ahb_rdata = out_reg[ 95:64];
            16'h001C: ahb_rdata = out_reg[ 63:32];
            16'h0020: ahb_rdata = out_reg[ 31: 0];
            default:ahb_rdata = 32'hFFFFFFFF;
        endcase
    end else 
        ahb_rdata = 32'hFFFFFFFF;

assign AHB_HRDATA = ahb_rdata;

aes_top  u_aes_top (
    .clk                     ( AHB_HCLK      ),//
    .rst_n                   ( AHB_HRESETn   ),//
    .keyexp                  ( keyexp        ),
    .encode                  ( encode        ),
    .data                    ( data_reg       ),//

    .keyexp_done             ( keyexp_done   ),
    .encode_done             ( encode_done   ),
    .out                     ( outtxt        )
);

endmodule
